/**
 * @package Infinity-Seed
 * @subpackage save
 *
 * @copyright Copyright (C) 2012-2013 Exia.CESI
 * @author Paul MAGNIN, Arthur MERCIER, Jordan RICHET, Cyril SCHUMACHER
 */
package save;

import java.awt.Dimension;

/**
 * Gestion des sauvegardes (Strategy Pattern).
 * @author Cyril SCHUMACHER <cyril.schumacher at viacesi.fr>
 * @author Jordan RICHET <jordan.richet at viacesi.fr>
 */
public class SaveGrid 
{
    /**
     * Format de la sauvegarde.
     */
    private ISave _format;
    
    // <editor-fold defaultstate="collapsed" desc="Conversion d'une grille en un tableau d'entier.">
    /**
     * Conversion d'une grille en un tableau d'entier.
     * @param Grille.
     * @return Retourne un tableau d'entier.
     */
    private int[][] _gridStringToInt(String grid) {
        // Récupère les tailles retournees de la bdd à partir des getters de SaveDatabase.java
        int height = this._format.getHeight();
        int width = this._format.getWidth();
        // Crée tableau avec les valeurs ci dessus.
        int[][] gridInt = new int[height][width];
        /*
         * Découpe la chaîne de caractère après chaque virgule.
         * @see <a href="http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split(java.lang.String)">String::split()</a>
         */
        String[] gridTemporary = grid.split(",");
        /*
         * x = largeur, y = hauteur
         * ils permettent de definir les coordonnées.
         */
        int x = 0;
        int y = 0;
        /*
         * String gridString : chaine1 permet de parcourir chaine1 et de les stockés dans gridString
         */
        for(String gridString : gridTemporary)
        {
            //Interger.parseInt permet de de stocké dans le tableau gridInt
            gridInt[y][x] = Integer.parseInt(gridString);
            // -1 car on commence pas par 1 mais 0
            if (x >= gridInt[0].length - 1) { 
                x = 0;
                y++;
            }
            else {
                x++;
            }
        }
        
        return gridInt;
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Conversion d'une grille en une chaîne de caractère.">
    /**
     * Conversion d'une grille en une chaîne de caractère.
     * @param Grille.
     * @return Retourne un tableau en une chaîne de caractère.
     */
    private String _gridIntToString(int[][] grid) {
        // On crée une chaîne de caractère.
        String gridString = new String();
        /*
         * On parcours la grille pour ensuite le mettre dans le gridString avec entre chaques états une virgule pour les differenciés.
         */
        for(int i = 0; i < grid.length; i++) {
            for(Integer cell : grid[i]) {
                gridString += cell.toString() + ",";
            }
        }
        
        return gridString;
    }
    // </editor-fold>
    
    /**
     * Définit le type de format.
     * @param format Instance.
     */
    public void setBehaviour(ISave format) {
        this._format = format;
    }
    
    /**
     * Récupère le tableau.
     * @return Retourne un tableau multi-dimensionnel.
     * @see SaveGrid#_gridStringToInt()
     */
    public int[][] getGrid() {
        return this._gridStringToInt(this._format.getGrid());
    }
    
   
    /**
     * Sauvegarde une grille.
     * @param size Taille de la grille.
     * @param stepNumber Nombre de pas.
     * @param timeNumber Temps entre chaque pas.
     * @param grid Grille.
     * @return Retourne TRUE si la grille a ete sauvegardee, FALSE si une erreur est survenue.
     * @see SaveGrid#_gridIntToString()
     */
    public Boolean setGrid(Dimension size, int stepNumber, int timeNumber, int[][] grid) {
        return this._format.setGrid(size, stepNumber, timeNumber, this._gridIntToString(grid));
    }
    
    /**
     * Vérifie si une sauvegarde existe.
     * @return Retourne TRUE si une sauvegarde existe, FALSE sinon.
     */
    public Boolean exists(){
        return this._format.exists();
    }
}
